#ifndef _CACTION_H_
#define _CACTION_H_

#include "Main.h"
#include "CPlayer.h"

class CPlayer;


//A CAction is an action of a CPlayer.  Anything the CPlayer does anything, it is represented by a CAction.
// CAction is the base class for all other actions.

// In order to create an action, all you have to do is construct it, and call the AssignToPlayer function.
class CAction
{

public:
	//Enumerators
	enum ACTION_TYPE {
		ACTION_JUMP   = 0,
		ACTION_SPRINT = 1,
		ACTION_CROUCH = 2,

		ACTION_FORCE_32BIT = 0x7FFFFFFF
	};


	//Constructors
	CAction();
	virtual ~CAction();

	//Some virtuals
	virtual  ACTION_TYPE GetActionType( )  = 0;
	virtual  bool        Perform      (float param1 = 0.0f, float param2 = 0.0f, float param3 = 0.0f, float param4 = 0.0f)  = 0;
	

	//Other public functions
	virtual void     Complete() { m_bIsPerforming = false; }
	virtual void     AssignToPlayer(CPlayer * player);
	//by default an Action cannot perform more than once at a time.
	bool     CanPerform() { return (m_bCanPerform && !m_bIsPerforming); }
	bool     IsPerforming() { return m_bIsPerforming; }


protected:
	
	//--Protected instance variables--
	//the player we are performing actions on
	CPlayer * m_pPlayer;
	//this will be true depending on the child class.
	bool      m_bCanPerform;
	//this will be true after the CPlayer queries the Action to perform.
	bool      m_bIsPerforming;
	

};


class CActionJump : public CAction
{	

public:
	//Constructors
	CActionJump();

	//Some virtuals
	ACTION_TYPE GetActionType( ) { return CAction::ACTION_JUMP; }
	bool        Perform      (float param1, float param2 = 0.0f, float param3 = 0.0f, float param4 = 0.0f);
	void        Complete     ( );
	

};


class CActionSprint : public CAction
{	

public:
	//Constructors
	CActionSprint();

	//Some virtuals
	ACTION_TYPE GetActionType( ) { return CAction::ACTION_SPRINT; }
	bool        Perform      (float param1, float param2 = 0.0f, float param3 = 0.0f, float param4 = 0.0f);
	void        Complete     ( );
	
private:
	float oldFOV;
	float oldMaxVelXZ;

};

class CActionCrouch : public CAction
{	

public:
	//Constructors
	CActionCrouch();

	//Some virtuals
	ACTION_TYPE GetActionType( ) { return CAction::ACTION_CROUCH; }
	bool        Perform      (float param1, float param2 = 0.0f, float param3 = 0.0f, float param4 = 0.0f);
	void        Complete     ( );
	

}; 

#endif